package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelService;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.tool.HttpTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
 * 严选官方接口
 * **/
@Slf4j
public class Plugin_ECARD_P007 implements ChannelService {
    public ChannelResult QueryBalance(JSONObject apiConfig){
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }
    public  ChannelResult Submit(JSONObject apiConfig, Map<String,Object> data){

        try {

            JSONObject dataConfig= JSONObject.parseObject(JSONObject.toJSONString(data));
            String price=new BigDecimal(String.valueOf(data.get("PurchasePrice"))).scaleByPowerOfTen(2).stripTrailingZeros().toPlainString();
            String productId = apiConfig.getString("productId");


            DateTimeFormatter dft=DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            String curTime =String.valueOf(System.currentTimeMillis());
            String nonceStr =dft.format(LocalDateTime.now());
            Map<String,String> dataParams=new LinkedHashMap<>();
            dataParams.put("promId",dataConfig.getString("SUPProductId"));
            dataParams.put("outTradeNo", dataConfig.getString("ChannelOrderCode"));
            dataParams.put("outPayTime",curTime);
            dataParams.put("outPayPrice",price);
            dataParams.put("rechargeType","1");
            dataParams.put("rechargeAccount",String.valueOf(data.get("AccountVal")));
            dataParams.put("productId",productId);
            dataParams.put("appId", apiConfig.getString("USERID"));
            dataParams.put("timestamp", curTime);
            dataParams.put("nonceStr",nonceStr);
            dataParams.put("signType","MD5");

            String sstr=getSignStr(dataParams);


            dataParams.put("sign", stringToMD5(sstr + "&key=" + apiConfig.getString("SecretKey")).toUpperCase());


            String url=apiConfig.getString("SubmitURL");
            String res= HttpTool.sendPost(url,dataParams);
            JSONObject retobj = JSONObject.parseObject(res);
            String status=retobj.getString("code");
            String errMsg=retobj.getString("msg");
            if("20000".equals(status)){
                return ChannelResult.IN_PROCESS();

            }else {
                return ChannelResult.FAILED(status+","+errMsg);
            }
        }catch (Exception ex){
            ex.printStackTrace();
            log.error("严选提交订单接口错误：",ex);
            return  ChannelResult.error("严选提交订单接口错误");
        }

    }
    public  ChannelResult Query(JSONObject apiConfig,Map<String,Object> data) {
        try {

            JSONObject dataConfig= JSONObject.parseObject(JSONObject.toJSONString(data));
            String productId = apiConfig.getString("productId");

            DateTimeFormatter dft=DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
            String curTime =String.valueOf(System.currentTimeMillis());
            String nonceStr =dft.format(LocalDateTime.now());
            Map<String,String> dataParams=new LinkedHashMap<>();
            dataParams.put("outTradeNo", dataConfig.getString("ChannelOrderCode"));
            dataParams.put("appId", apiConfig.getString("USERID"));
            dataParams.put("timestamp", curTime);
            dataParams.put("nonceStr",nonceStr);
            dataParams.put("productId",productId);
            dataParams.put("signType","MD5");

            String sstr=getSignStr(dataParams);


            dataParams.put("sign", stringToMD5( sstr + "&key=" + apiConfig.getString("SecretKey")).toUpperCase());

            String url = apiConfig.getString("QueryURL");
            String res= HttpTool.sendPost(url,dataParams);
            JSONObject retobj = JSONObject.parseObject(res);
            String status=retobj.getString("code");
            String errMsg=retobj.getString("msg");
            if ("20000".equals(status)) {
                JSONObject response=retobj.getJSONObject("data");
                String state=response.getString("tradeStatus");

                if ("1".equals(state) || "2".equals(state))
                {
                    return  ChannelResult.success("充值成功");
                }
                else if ("3".equals(state) || "4".equals(state))
                {
                    return ChannelResult.FAILED(state+","+errMsg);
                }else  if ("0".equals(state)){
                    return ChannelResult.FAILED("订单不存在");
                }
                return  ChannelResult.error(state);

            }
            else {
                return ChannelResult.error(status+","+errMsg);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            log.error("严选查询订单接口错误：", ex);
            return ChannelResult.error("严选查询订单接口错误");
        }
    }


    public  ChannelResult Notify(JSONObject apiConfig,Map<String,Object> data){
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");

    }

    public static String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        StringBuilder md5code = new StringBuilder();
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText.getBytes("UTF-8"));
            md5code = new StringBuilder(new BigInteger(1, secretBytes).toString(16));
            while (md5code.length() < 32) {
                md5code.insert(0, "0");
            }
        } catch (Exception ex) {
            log.error("md5加密异常：" + ex.getMessage(), ex);
        }

        return md5code.toString();
    }

    public static String getSignStr(Map<String, String> map) {
        String result = "";
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(map.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {

                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造签名键值对的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (item.getKey() != null && item.getKey() != "") {
                    String key = String.valueOf(item.getKey());
                    String val = String.valueOf(item.getValue());
                    if(sb.length()>0){
                        sb.append("&");
                    }
                    if (StringUtils.hasLength(val)) {
                        sb.append(key +"="+ val);
                    }
                }
            }
            result = sb.toString();
        } catch (Exception e) {
            log.error("获取签名明文出错：", e);
            return null;
        }
        return result;
    }
}
